---
title: Customizing Patterns
description:
  Panda provides the ability to customize the built-in patterns, as well as creating your own custom patterns. This is
  useful to create your own layout pattern abstractions that can be used in your application.
---

Panda allows you to customize built-in patterns and create custom patterns for reusable layout abstractions.

A pattern accepts the following parameters:

- `description` - The description of the pattern.
- `properties` - The list of properties that the pattern accepts.
- `defaultValues` - The default values for the properties. This is useful when you want to provide a default value for a
  property.
- `transform` - The function that accepts the properties and returns a css object.
- `jsx` - The name of the JSX component that will be generated (when `jsxFramework` is set). Defaults to the pascal-case
  version of the pattern name.
- `jsxElement` - The actual JSX element that will be rendered (when `jsxFramework` is set). Defaults to `div`.
- `blocklist` - The list of properties that are not allowed to be used in the pattern. Can be used to ensure strict
  typings when using the pattern.
- `strict` - Whether to only generate types for the specified properties. This will disallow css properties.

## Creating a Pattern

To create a pattern, you can use the `patterns` property in the config. Let's say we want to create a "Scrollable"
pattern that applies preset styles to a container that allows for scrolling.

```js
const config = {
  patterns: {
    extend: {
      scrollable: {
        description: 'A container that allows for scrolling',
        defaultValues: {
          direction: 'vertical',
          hideScrollbar: true
        },
        properties: {
          // The direction of the scroll
          direction: { type: 'enum', value: ['horizontal', 'vertical'] },
          // Whether to hide the scrollbar
          hideScrollbar: { type: 'boolean' }
        },
        // disallow the `overflow` property (in TypeScript)
        blocklist: ['overflow'],
        transform(props) {
          const { direction, hideScrollbar, ...rest } = props
          return {
            overflow: 'auto',
            height: direction === 'horizontal' ? '100%' : 'auto',
            width: direction === 'vertical' ? '100%' : 'auto',
            scrollbarWidth: hideScrollbar ? 'none' : 'auto',
            WebkitOverflowScrolling: 'touch',
            '&::-webkit-scrollbar': {
              display: hideScrollbar ? 'none' : 'auto'
            },
            ...rest
          }
        }
      }
    }
  }
}
```

Then you can run the following command to generate the pattern JS code:

<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
  {/* <!-- prettier-ignore-start --> */}
  <Tab>
    ```bash
    pnpm panda codegen
    ```
  </Tab>
  <Tab>
    ```bash
    npm panda codegen
    ```
  </Tab>
  <Tab>
    ```bash
    yarn panda codegen
    ```
  </Tab>
  <Tab>
    ```bash
    bun panda codegen
    ```
  </Tab>
  {/* <!-- prettier-ignore-end --> */}
</Tabs>

Now you can import the pattern and use it in your application:

```js
import { scrollable } from '../styled-system/patterns'

const App = () => {
  return (
    <div className={scrollable({ direction: 'vertical', hideScrollbar: true })}>
      <div>Scrollable content</div>
    </div>
  )
}
```

## Customizing Built-in Patterns

You can extend the [default patterns](/docs/concepts/patterns#predefined-patterns) by using the `patterns.extend`
property in the config.

```ts filename="panda.config.ts"
import { defineConfig } from '@pandacss/dev'

export default defineConfig({
  patterns: {
    extend: {
      // Extend the default `flex` pattern
      flex: {
        properties: {
          // only allow row and column
          direction: { type: 'enum', value: ['row', 'column'] },
          jsx: ['Flex', 'CustomFlex'] // 👈 match the `CustomFlex` component to this pattern
        }
      }
    }
  }
})
```

Then you can run the following command to update the pattern JS code:

<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
  {/* <!-- prettier-ignore-start --> */}
  <Tab>
    ```bash
    pnpm panda codegen
    ```
  </Tab>
  <Tab>
    ```bash
    npm panda codegen
    ```
  </Tab>
  <Tab>
    ```bash
    yarn panda codegen
    ```
  </Tab>
  <Tab>
    ```bash
    bun panda codegen
    ```
  </Tab>
  {/* <!-- prettier-ignore-end --> */}
</Tabs>

## Minimal setup

If you want to use Panda with the bare minimum, without any of the defaults, you can read more about it
[here](/docs/guides/minimal-setup)
